<template>
    <div class="bi-tree" :class="type">
        <tree-item v-for="(item,index) in list" :key="item.__id" :item="item" :position="itemPosition(index)" :last="index==list.length-1"  ></tree-item>
    </div>
</template>

<script>
import TreeItem from './tree-item.vue';
export  default {
    emits:['updateCheck','updateFold','titleClick'],
    components:{
        TreeItem
    },
    provide() {
        return {
            itemKey:this.itemKey,
            checkbox:this.checkbox,
            titleKey:this.titleKey,
            type:this.type,
            childrenClick:this.childrenClick,
            disabledNode:this.disabledNodeList,
            updateCheck:(key,check)=>{
                
                if (check){
                    if (!this.checkList.includes(key)){
                        this.checkList.push(key);
                    } 
                }else{
                    if(this.checkList.indexOf(key)>=0)  this.checkList.splice(this.checkList.indexOf(key),1);
                }
                
            },
            updateFold:(itemKey,fold)=>{

                this.foldData[itemKey] = fold;
               
               if (this.storagename!= '') {
                    localStorage.setItem(this.storagename,JSON.stringify(this.foldData));
               }
               
               this.$emit('updateFold',this.foldData);
            },
            titleClick:(item)=>{
                this.$emit('titleClick',item);
            },
            
        }
    },
    computed:{
        disabledNodeList(){
            
            let list = [];
            
            for(let i in this.disabledNode){
                let element = this.disabledNode[i];
                if (element!==undefined){
                    if (typeof element.toString === 'function'){
                        list.push(element.toString());
                    }else{
                        list.push(element);
                    }
                }

            }
            return list;
        }
    },
    props:{
        data:{
            type:Array,
            default:[]
        },
        type:{
            type:String,
            default:'default' // default,menu
        },
        checkbox:{
            type:Boolean,
            default:false
        },
        itemKey:{
            type:String,
            default:''
        },
        titleKey:{
            type:String,
            default:'title'
        },
        defaultFold:{
            type:Boolean,
            default:true
        },
        checked:{
            type:Array,
            default:[]
        },
        checkedInherit:{ // 继承父级的选择状态
            type:Boolean,
            default:false
        },
        storagename:{
            type:String,
            default:''
        },
        childrenClick:{
            type:Boolean,
            default:false
        },
        disabledNode:{
            type:Array,
            default:[]
        }
    },
    data(){

        let foldData = {};

        if (this.storagename != '') {
            fold =  localStorage.getItem(this.storagename);
            if (fold){
                foldData = JSON.parse(fold);
            }
        }
            
        return {
            list:[],
            checkList:JSON.parse(JSON.stringify(this.checked))??[],
            foldData
        }
    },
    methods:{
        itemPosition(index){
            if (index == 0) return 'frist';
            else if (index == this.list.length-1) return 'last';
            else return 'middle';
        },
        itemLevel(index){
            let level = [];
            if (index ==  this.list.length-1)  level.push(false);
            else  level.push(true);

            return level;
        },
        childrenPostCheck(id,check,halfCheck){


            let checkList = [];

            let checkALLData = (list)=>{
                for(let i in list){
                    let item = list[i];
                    if (this.checkList.includes(item[this.itemKey])){
                        if (item.disabled && item.disabled == true ){
                            
                        }else{
                            checkList.push(item[this.itemKey]);
                        }
                    }
                    if (item.children && item.children.length>0){
                         checkALLData(item.children);
                    }
                    
                }
            }

            checkALLData(this.list);
            this.$emit('updateCheck',checkList);
        },
        parseData(data,parent = 0,check = false,disabled = false){
            let list  = [];


            let checkAndHalfCheck =  (childrens) =>{
                let checkCount = 0;
                let halfCheckCount = 0;
                let _check = false;
                let _halfCheck = false;
                for(let i in childrens){
                    if (childrens[i].check) checkCount++;
                    if (childrens[i].halfCheck) halfCheckCount++;
                }

                if (checkCount === childrens.length){
                    _check = true;
                    _halfCheck = false;
                }

                if (checkCount > 0 && checkCount < childrens.length || halfCheckCount > 0){
                    _halfCheck = true;
                    _check = false;
                }

                if (checkCount ==0 && halfCheckCount ==0){
                    _check = false;
                    _halfCheck = false;
                }

                return {check:_check,halfCheck:_halfCheck}
            }




            for(let i in data){
                let item = data[i];
                if (item){
                    item.__id =  parent + '_' + i;
                    item.check = (this.checkedInherit && check) || item.check || this.checked.includes(item[this.itemKey]);
                    item.fold = this.foldData[item[this.itemKey]]??this.defaultFold;
                    
                    item.disabled = disabled || this.disabledNodeList.includes(item[this.itemKey]);


                    if (item.children && item.children.length>0){
                        item.children = this.parseData(item.children,item.__id,item.check,item.disabled);
                        let checkValue = checkAndHalfCheck(item.children);
                        item.check = checkValue.check;
                        item.halfCheck = checkValue.halfCheck;  
                    }

                    list.push(item);
                }
               
                
            }

            return list;
        }
    },
    watch:{
        data(val){
            this.list = this.parseData(val);
        }
    },
    mounted(){
       this.list=  this.parseData(this.data);
    }
}
</script>

<style>
 
</style>